package controller;

import helper.Balance;
import helper.Formatter;
import helper.UserSession;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import model.*;

import org.mybeans.dao.DAOException;

import databeans.*;

/*
 * @Xiao Liang
 * Employee Use Case: View Customer Account
 * 
 */
public class EmployeeViewCustomerAccountAction extends Action{

	private CustomerDAO customerDAO;
	private PositionDAO positionDAO; 
	private TransactionDAO transactionDAO; 
	private FundHistoryDAOSQL fundHistoryDAOSQL; 
	private FundDAO fundDAO; 

	public EmployeeViewCustomerAccountAction(Model model) {
		customerDAO = model.getCustomerDAO();
		positionDAO = model.getPositoinDAO(); 
		fundHistoryDAOSQL = model.getFundHistoryDAOSQL(); 
		transactionDAO = model.getTransactionDAO(); 
		fundDAO = model.getFundDAO(); 
	}

	public String getName() { return "employeeViewCustomerAccount.do"; }

	public String perform(HttpServletRequest request) {
        // define target page
        String loginPageAjax   = "common/messages.jsp";
        String loginPage   = "employee/employee-login.jsp";
        String successPage = "employee/view-customer-account.jsp"; 
        String originPage  = successPage;
        
        // Set up the errors list
        List<String> errors = new ArrayList<String>();
        request.setAttribute("errors",errors);
        
        String type = (String)request.getParameter("type");
        System.out.println("================= >>> type = " + type);
        
        Employee employee = null;
        Customer customer = null;
        //check if employee has been logged in

        //request.getSession() will return the current session and if one does not exist, a new session will be cretaed.
        //request.getSession(true) will return the current session if one exists, if one doesn't exits a new one will be created.
        //So there is actually no difference between the two methods HOWEVER, if you use request.getSession(false), it will return the current session if one exists and if one DOES NOT exist a new one will NOT be cretaed.
        employee = UserSession.getLoggedInEmployee(request);
        if (employee == null) {
        	if(type!=null && type.equals("ajax"))
        	{
        		errors.add("Your session has timed out. Please Login again. <a href=\"employeeHome.do\">Login</a> ");
        		return loginPageAjax;
        	}else
        	{
        		errors.add("You need to log in");
                return loginPage ;
        	}
        }
        
        //check if customer has actually logged in
        customer = UserSession.getLoggedInCustomer(request);
        if (customer != null) {
            request = UserSession.removeCustomerFromSession(request);
            errors.add("This section is closed for customer");
            return loginPage;
        }
        

        
		try {

	        
	        /*
	         * Employee should click on or type in a customer ID in order to view customer account
	         */
	        String txtCustomerID = request.getParameter("customerID");
	        System.out.println(txtCustomerID);
	        if((txtCustomerID==null)||(txtCustomerID.trim().equals("")))return originPage; 
	        
  			int customerID = Integer.parseInt(txtCustomerID); 
  			customer = customerDAO.lookup(customerID); 
  			System.out.println("Start perform - 1");
  			
  			if(customer == null){
  				System.out.println("There is no customer associated with ID: "+txtCustomerID);
  				errors.add("There is no customer associated with ID: "+txtCustomerID);
  				return successPage;
  			}
  			
  			request.setAttribute("customerID", txtCustomerID); 
  			//display name
  			String firstName = customer.getFirstName();
  			String lastName  = customer.getLastName();
  			String name      = firstName+" "+lastName; 
  			request.setAttribute("name", name); 
  			request.setAttribute("email", customer.getEmail());
  			
  			//display address
  			String addrLine1 = customer.getAddrLine1();
  			String addrLine2 = customer.getAddrLine2();
  			String addr; 
  			if(addrLine2!=null) addr = addrLine1+" "+addrLine2;
  			else addr=addrLine1; 
  			request.setAttribute("address", addr);
  			
  			System.out.println("Start perform - 2");
  			
  			//display date of last trading day
  			Date lastTradingDate = transactionDAO.getLastTradingDate(customerID); 
  			String lastTradingDateString = null; 
  			/*new Date(18000) is default date*/
  			Date lastSubmissionDate = transactionDAO.getLastSubmissionDate(customerID); 
  			String lastSubmissionDateString=null; 
  			if(lastTradingDate.equals(new Date(18000))){
  				SimpleDateFormat sdf = new SimpleDateFormat("dd MMM, yyyy"); 
  				if(!(lastSubmissionDate.equals(new Date(18000))))lastSubmissionDateString = sdf.format(lastSubmissionDate); 
  				else lastSubmissionDateString=" - "; 
  			}else {
  				SimpleDateFormat sdf = new SimpleDateFormat("dd MMM, yyyy"); 
  				lastTradingDateString = sdf.format(lastTradingDate);  
  			}
  			request.setAttribute("lastTradingDate", lastTradingDateString); 
  			request.setAttribute("lastSubmissionDate", lastSubmissionDateString);
  			
  			System.out.println("Start perform - 3");
  			
  			DecimalFormat twoDForm = new DecimalFormat("#.##"); 
  			
  			//display cash balance
  			double cash      = customer.getCash(); 
  		
  			request.setAttribute("cashBalance", Double.parseDouble(Formatter.prepCashToView(customer.getCash()))); 
  			System.out.println("Start perform - 4");
  			
  			//display available cash
  			double availableCash = Double.parseDouble(Formatter.prepCashToView(Balance.getCustomerAvailableCash(customer)));
  			System.out.println("availableCash = " + availableCash);
  			request.setAttribute("availableCash", twoDForm.format(availableCash)); 
  			
  			System.out.println("Start perform - 5");
  			
  			/*
  			 * display number of shares of each fund owned
  			 * : get Positions with customerID
  			 * to retrieve fundID: position[i].getFundID();
  			 * to retrieve shares: position[i].getShares(); 
  			 */
  			 Position[] positions = positionDAO.getPositions(customerID); 
  			 request.setAttribute("positions", positions); 
  			
  			/*
  			 * display the value of that position = shares * price of fund 
  			 * : obtain a list of value corresponding to fund
  			 */
  			 List<Double> values = new ArrayList<Double>();
  			 
    		/*
    		 * display the fund name
    		 * : obtain a list of fundName corresponding to fund id
    		 */
   			 List<String> fundNames = new ArrayList<String>(); 
   			 
  			 for (int i=0; i<positions.length; i++){
  			 	double shares           = Double.parseDouble(Formatter.prepShareToView(positions[i].getShares()));
  			 	int fundID              = positions[i].getFundID(); 
  			 	
  			 	//TODO: What is the relationship between FundHistory price-date,last trading date, should we contain 
  			 	//  	hh:mm:ss, or just yyyy-MM-dd
  			 	
  			 	Fund fund = fundDAO.lookup(fundID);
  			 	fundNames.add(fund.getName()); 
  			 	
  			 	Calendar cal=Calendar.getInstance();
  			 	cal.setTime(lastTradingDate);
  		  		FundHistory fundHistory = fundHistoryDAOSQL.lookup(fundID,cal); 
  		  		if(fundHistory==null) {
  		  		   values.add(0.00);  //if no fund history, transaction is pending, position is zero. 
  		  		}else{  	
  		  		double price            = Double.parseDouble(Formatter.prepCashToView(fundHistory.getPrice())); 
  		  		double tempValue = price * shares ; 
  		  		values.add(new Double(shares*price)); 
  		  		}
  			 }
  		  	    
  			request.setAttribute("values", values); 
  			request.setAttribute("fundNames", fundNames); 

	        return successPage;
        } catch (DAOException e) {
        	errors.add("Employee View Customer Account Failed: "+e.getMessage());
        	return originPage;
        }
    }
	
}
